package com.wl.wuliu.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wl.wuliu.entity.*;
import com.wl.wuliu.exception.GlobalExceptionHandler;
import com.wl.wuliu.mapper.TruckMapper;
import com.wl.wuliu.result.AjaxResult;
import com.wl.wuliu.service.DriverService;
import com.wl.wuliu.service.FinanceService;
import com.wl.wuliu.service.SysUserService;
import com.wl.wuliu.service.TruckService;
import com.wl.wuliu.utils.DateUtils;
import com.wl.wuliu.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author: gutaozhen
 * @Date: 2024/5/15
 */
@Service
public class TruckServiceImpl extends ServiceImpl<TruckMapper, Truck> implements TruckService {
    public static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @Autowired
    private TruckMapper truckMapper;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private FinanceService financeService;
    @Autowired
    private DriverService driverService;


    @Override
    public List<Truck> findList(QueryEntity queryEntity) {

        List<Truck> list = truckMapper.findList(queryEntity);
        return list;
    }

    @Override
    public AjaxResult saveTruck(Truck truck) {

        truck.preInsert();
        save(truck);
        truck.setCarStatus("1");
        log.info("添加运输车辆信息成功，id为：{}", truck.getId());

        return AjaxResult.success("添加成功！");
    }

    @Override
    public AjaxResult updateTruck(Truck truck) {

        log.info("修改运输车辆信息，修改前的信息为：{}", truck);
        truck.preUpdate();
        updateById(truck);
        truck.setCarStatus("1");
        log.info("修改运输车辆信息成功");

        return AjaxResult.success("修改成功！");
    }

    @Override
    public AjaxResult deleteTruck(String id) {

        removeById(id);
        log.info("删除运输车辆信息成功，id为：{}", id);

        return AjaxResult.success("删除成功！");
    }

    @Override
    public Truck getTruck(String id) {

        Truck truck = getById(id);

        //设置联络员和司机
        if (truck != null) {
            if (!StringUtils.isEmpty(truck.getUserId())) {
                SysUser sysUser = sysUserService.getById(truck.getUserId());
                if (sysUser != null && !StringUtils.isEmpty(sysUser.getNickName())) {
                    truck.setNickName(sysUser.getNickName());
                }
            }
            //设置司机信息
            if (!StringUtils.isEmpty(truck.getDriverId())) {
                Driver driver = driverService.getById(truck.getDriverId());
                if (driver != null) {
                    truck.setDriverName(driver.getDriverName());
                    truck.setDriverMobile(driver.getDriverMobile());
                    truck.setCarNumber(driver.getCarNumber());
                }
            }

        }

        return truck;
    }

    @Override
    public AjaxResult updateTruckStatus(Truck truck) {

        Truck truck1 = new Truck();
        truck1.setId(truck.getId());
        truck1.setCarStatus(truck.getCarStatus());
        //确认发车
        if ("2".equals(truck.getCarStatus())) {
            truck1.setInstallWeight(truck.getInstallWeight());
            truck1.setInstallLocation(truck.getInstallLocation());
            truck1.setUninstallLocation(truck.getUninstallLocation());
            truck1.setStartTime(new Date());
        }else if ("3".equals(truck.getCarStatus())) {
            //确认卸货
            truck1.setUninstallWeight(truck.getUninstallWeight());
            truck1.setEndTime(new Date());

            Truck byId = getById(truck.getId());
            //亏吨数量
            if (byId.getInstallWeight() != null && truck.getUninstallWeight() != null) {
                truck1.setLossWeight(truck.getUninstallWeight().subtract(byId.getInstallWeight()).abs());
            }
            //生成对应的财务信息
            this.financeService.saveFinance(truck.getId());
        }else if ("4".equals(truck.getCarStatus())) {
            //车俩异常
            truck1.setReason(truck.getReason());
            truck1.setHandleStatus("1");

            //处理异常
            if ("2".equals(truck.getHandleStatus())) {
                truck1.setHandleStatus("2");
                truck1.setHandleResult(truck.getHandleResult());
                truck1.setRemark(truck.getRemark());

                truck1.setUninstallWeight(truck.getUninstallWeight());
                truck1.setEndTime(new Date());

                Truck byId = getById(truck.getId());
                //亏吨数量
                if (byId.getInstallWeight() != null && truck.getUninstallWeight() != null) {
                    truck1.setLossWeight(truck.getUninstallWeight().subtract(byId.getInstallWeight()).abs());
                }

                //生成对应的财务信息
                this.financeService.saveFinance(truck.getId());
            }
        }else {
            return AjaxResult.error("非法参数");
        }

        truck1.preUpdate();
        updateById(truck1);

        return AjaxResult.success("操作成功！");
    }

    @Override
    public Map<String,List<String>> statisticsCarNumber(String startTime, String endTime) {

        //填入默认查询时间（当天）
        if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
            Date nowDate = new Date();
            endTime = DateUtils.format(nowDate, "yyyy-MM-dd");
            startTime = DateUtils.format(nowDate, "yyyy-MM-dd");
        }

        List<StatisticsResult> statisticsResults = truckMapper.statisticsCarNumber(startTime, endTime);

        Map<String,List<String>> data = new HashMap<>();
        List<String> nameList = statisticsResults.stream().map(StatisticsResult::getName).collect(Collectors.toList());
        data.put("name",nameList);
        List<String> valueList = statisticsResults.stream().map(StatisticsResult::getValue).collect(Collectors.toList());
        data.put("value",valueList);
        return data;
    }

    @Override
    public void importTruck(MultipartFile file) {
        try {
            //获取文件的输入流
            InputStream inputStream = file.getInputStream();
            List<TruckExport> list = EasyExcel.read(inputStream) //调用read方法
                    //注册自定义监听器，字段校验可以在监听器内实现
                    .registerReadListener(new TruckListener())
                    .head(TruckExport.class) //对应导入的实体类
                    .sheet(0) //导入数据的sheet页编号，0代表第一个sheet页，如果不填，则会导入所有sheet页的数据
                    .headRowNumber(1) //列表头行数，1代表列表头有1行，第二行开始为数据行
                    .doReadSync(); //开始读Excel，返回一个List<T>集合，继续后续入库操作

            Truck truck;
            Finance finance;
            QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
            QueryWrapper<Driver> driverQueryWrapper = new QueryWrapper<>();
            int count = 1;
            for (TruckExport truckExport : list) {
                truck = new Truck();
                sysUserQueryWrapper.clear();
                sysUserQueryWrapper.eq("nick_name", truckExport.getNickName());
                SysUser sysUser = sysUserService.getOne(sysUserQueryWrapper);
                truck.setUserId(sysUser.getId());

                driverQueryWrapper.clear();
                driverQueryWrapper.eq("car_number", truckExport.getCarNumber());
                Driver driver = driverService.getOne(driverQueryWrapper);
                if (driver == null) {
                    //新增一个司机
                    driver = new Driver();
                    driver.setCarNumber(truckExport.getCarNumber());
                    driver.setDriverMobile(truckExport.getDriverMobile());
                    driver.setUserId(sysUser.getId());
                    driver.preInsert();
                    driverService.save(driver);
                }else {
                    if (StringUtils.isEmpty(driver.getDriverMobile())) {
                        driver.setDriverMobile(truckExport.getDriverMobile());
                        driverService.updateById(driver);
                    }
                }
                truck.setDriverId(driver.getId());

                Date date = DateUtils.stringToDate("2024." + truckExport.getEndTime(), "yyyy.MM.dd");
                truck.setGoods(truckExport.getGoods());
                truck.setInstallLocation(truckExport.getInstallLocation());
                truck.setInstallWeight(truckExport.getInstallWeight());
                truck.setUninstallLocation(truckExport.getUninstallLocation());
                truck.setUninstallWeight(truckExport.getUninstallWeight());
                truck.setLossWeight(truckExport.getLossWeight());
                truck.setStartTime(date);
                truck.setEndTime(date);
                truck.setCarStatus("3");
                truck.setId(IdUtil.fastSimpleUUID());
                truck.setCreateTime(date);
                truck.setUpdateTime(date);
                truck.setDelFlag("0");

                save(truck);

                finance = new Finance();

                finance.setTruckId(truck.getId());
                finance.setLossPrice(truckExport.getLossPrice());
                finance.setLossAmount(truckExport.getLossAmount());
                finance.setPrice(truckExport.getPrice());
                finance.setGiveCar(truckExport.getGiveCar());
                finance.setInfoAmount(truckExport.getInfoAmount());
                finance.setAdvance(truckExport.getAdvance());
                finance.setPayment(truckExport.getPayment());
                if (!StringUtils.isEmpty(truckExport.getPaymentTime())) {
                    finance.setPaymentTime(DateUtils.stringToDate("2024."+truckExport.getPaymentTime(), "yyyy.MM.dd"));
                }
                finance.setReplyAmount(truckExport.getReplyAmount());
                finance.setProfit(truckExport.getProfit());

                truck.setId(IdUtil.fastSimpleUUID());
                truck.setCreateTime(date);
                truck.setUpdateTime(date);
                truck.setDelFlag("0");
                financeService.save(finance);

                log.info("导入成功一个，第{}个", count);
                count++;

            }

        }catch (IOException exception){
            throw new  RuntimeException(exception);
        }
    }
}
